package cs236369.hw5.db.beans;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.apache.log4j.Logger;

import cs236369.hw5.db.DbBean;
import cs236369.hw5.rest.beans.UserRegisterBean;

@Entity
@Table(name = "USERS")
public class DbUser implements Comparable<DbUser>, DbBean
{

	//hibernate field name
	public static final String USERNAME = "username";
	@Id
	@Column(name = "USERNAME", unique = true, nullable = false, length = 64)
	private String username;;

	@Column(name = "USERPASS", unique = false, nullable = false, length = 64)
	private String userpass;

	@Column(name = "SIRNAME", unique = false, nullable = false, length = 64)
	private String sirName;

	@Column(name = "LASTNAME", unique = false, nullable = false, length = 64)
	private String lastName;

	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinColumn(name = "ADDR_ID", nullable = true, insertable = true, updatable = true)
	private DbAddress address;

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL)
	private List<DbMessage> msgs = new LinkedList<DbMessage>();

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL)
	private List<DbUserRole> roles = new LinkedList<DbUserRole>();
	
	public DbUser(UserRegisterBean user)
	{
		this();
		this.username = user.getUsername();
		
		MessageDigest messageDigest = null;
        try
        {
        	//TODO digest the pass
	        messageDigest = MessageDigest.getInstance("MD5");
	        byte[] bin = messageDigest.digest((user.getPassword()).getBytes());
	        this.userpass = user.getPassword();
        }
        catch (NoSuchAlgorithmException e)
        {
        	//should never get here... 
	        Logger.getLogger(DbUser.class).error("md5 doesn't exists...", e);
	        this.userpass = null;
        }
		
		
		this.userpass = user.getPassword();
		this.sirName = user.getSirName();
		this.lastName = user.getLastName();
		DbAddress addr = new DbAddress(user.getAddress());
		if (null != addr.getCity() //
		        || null != addr.getCountry() //
		        || null != addr.getStreet())
		{
			this.address = addr;
		}

	}

	public DbUser(String username)
	{
		this();
		this.username = username;
	}

	public DbUser()
	{
		// empty ctor;Long
	}

	public String getUsername()
	{
		return username;
	}

	public void setUsername(String username)
	{
		this.username = username;
	}

	public String getUserpass()
	{
		return userpass;
	}

	public void setUserpass(String userpass)
	{
		this.userpass = userpass;
	}

	public String getSirName()
	{
		return sirName;
	}

	public void setSirName(String sirName)
	{
		this.sirName = sirName;
	}

	public String getLastName()
	{
		return lastName;
	}

	public void setLastName(String lastName)
	{
		this.lastName = lastName;
	}

	public DbAddress getAddress()
	{
		return address;
	}

	public void setAddress(DbAddress address)
	{
		this.address = address;
	}

	public List<DbMessage> getMsgs()
	{
		return msgs;
	}

	public void addMsg(DbMessage msg)
	{
		msgs.add(msg);
		msg.setUser(this);
	}

	public void setMsgs(List<DbMessage> msgs)
	{
		this.msgs = msgs;
	}

	public List<DbUserRole> getRoles()
    {
	    return roles;
    }

	public void addRole(String role)
	{
		roles.add(new DbUserRole(this,role));
	}
	
	public void setRoles(List<DbUserRole> roles)
    {
	    this.roles = roles;
    }

	@Override
	public int compareTo(DbUser o)
	{
		if (null == o || null == o.username)
		{
			return 1;
		}
		if (null == this.username)
		{
			return -1;
		}
		return this.username.compareTo(o.username);
	}
}
